package com.hsy.crm.web.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.cm.PageResult;
import com.hsy.crm.web.domain.cm.Unified;
import com.hsy.crm.web.domain.entity.CostOrder;
import com.hsy.crm.web.domain.entity.CostOrderDetail;
import com.hsy.crm.web.domain.entity.StoreProduct;
import com.hsy.crm.web.domain.po.costOrder.CostDetailPo;
import com.hsy.crm.web.domain.po.costOrder.CostGetPo;
import com.hsy.crm.web.domain.po.costOrder.CostOrderPagePo;
import com.hsy.crm.web.domain.vo.costOrder.CostOrderPageVo;
import com.hsy.crm.web.domain.vo.costOrder.CostVo;
import com.hsy.crm.web.mapper.CostOrderDetailMapper;
import com.hsy.crm.web.mapper.CostOrderMapper;
import com.hsy.crm.web.service.base.BaseService;
import com.hsy.crm.web.service.base.DataInitService;
import com.hsy.crm.web.utils.DateUtils;
import com.hsy.crm.web.utils.UuidUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class CostOrderService extends BaseService<CostOrder> {

    @Autowired
    CostOrderMapper costOrderMapper;

    @Autowired
    CostOrderDetailMapper costOrderDetailMapper;

    @Autowired
    StoreProductService storeProductService;

    @Transactional
    public Unified<CostOrder> insert(CostVo vo) {
        Unified<CostOrder> unified = new Unified<>();
        // order
        CostOrder order = vo.getOrder();
        order.setDate(getFullTime(vo.getDatestr()));
        order.setLoginCompanyId(vo.getLoginCompanyId());
        order.setCustomerId(vo.getCustomerId());
        order.setCode(DataInitService.getOrderCode());
        order.setLoginUserId(vo.getLoginUserId());
        order.setStatus(App.Status.BC);
        this.insert(order);
        vo.setOrder(order);
        //order details
        this.insertDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            this.examine(order);
        }

        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<CostOrder> update(CostVo vo) {
        CostOrder order = vo.getOrder();
        order.setDate(getFullTime(vo.getDatestr()));
        order.setLoginUserId(vo.getLoginUserId());
        order.setCustomerId(vo.getCustomerId());
        this.update(order);

        //order details
        this.deleteDetails(order);
        this.insertDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            this.examine(order);
        }

        Unified<CostOrder> unified = new Unified<>();
        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<Integer> delete(CostOrder costOrder) {
        Unified<Integer> unified = this.delete(costOrder);
        this.deleteDetails(costOrder);
        return unified;
    }

    @Transactional
    public Unified<Integer> examine(CostOrder order){
        Unified<Integer> unified = new Unified<>();
        // update status
        Long orderId = order.getId();
        this.updateStatus(orderId,App.Status.SH,order.getCustomerId());
        examStoreProduct(order);
        return unified;
    }

    @Transactional
    public Unified<Integer> doInvalid(CostOrder order){
        Unified<Integer> unified = new Unified<>();
        // update status
        this.updateStatus(order.getId(),App.Status.BC,order.getCustomerId());
        invalidStoreProduct(order);
        return unified;
    }

    public Unified<CostGetPo> getOrder(CostOrder order) {
        Unified<CostGetPo> unified = new Unified<>();
        String customerId = order.getCustomerId();
        order = costOrderMapper.selectByPrimaryKey(order);
        order.setCustomerId(customerId);
        List<CostDetailPo> details = costOrderMapper.findOrderDetails(order);
        CostGetPo po = new CostGetPo();
        po.setOrder(order);
        po.setDetails(details);
        unified.setData(po);

        return unified;
    }

    public PageResult<CostOrderPagePo> page(CostOrderPageVo costOrderPageVo) {
        Page page = PageHelper.startPage(costOrderPageVo.getPage(),costOrderPageVo.getLimit());
        PageResult<CostOrderPagePo> pageResult = new PageResult<>();
        pageResult.setRows(costOrderMapper.page(costOrderPageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    private void deleteDetails(CostOrder costOrder){
        CostOrderDetail detail = new CostOrderDetail();
        detail.setCustomerId(costOrder.getCustomerId());
        detail.setCostOrderId(costOrder.getId());
        costOrderDetailMapper.delete(detail);
    }

    private void insertDetails(CostVo vo){
        for(CostOrderDetail detail : vo.getDetails()){
            detail.setCostOrderId(vo.getOrder().getId());
            detail.setCustomerId(vo.getCustomerId());
            detail.setId(UuidUtils.getUuid());
            costOrderDetailMapper.insert(detail);
        }
    }

    private void updateStatus(Long orderId,Integer status,String customerId){
        CostOrder order = new CostOrder();
        order.setStatus(status);
        order.setId(orderId);
        order.setCustomerId(customerId);
        costOrderMapper.updateByPrimaryKeySelective(order);
    }

    private void examStoreProduct(CostOrder order){
        updateStoreProduct(order,App.ExamType.EXAMINE);
    }

    private void invalidStoreProduct(CostOrder order){
        updateStoreProduct(order,App.ExamType.INVALID);
    }

    private void updateStoreProduct(CostOrder order,int examType){
        List<CostOrderDetail> orderDetails = getCostOrderDetails(order);

        if( examType == App.ExamType.EXAMINE ){
            for( CostOrderDetail orderDetail : orderDetails ){
                orderDetail.setCustomerId(order.getCustomerId());
                StoreProduct storeProduct = getStoreProduct(orderDetail);
                storeProductService.update(storeProduct,App.Direction.ADD);
            }
        }else if( examType == App.ExamType.INVALID ){
            for( CostOrderDetail orderDetail : orderDetails ){
                orderDetail.setCustomerId(order.getCustomerId());
                StoreProduct storeProduct = getStoreProduct(orderDetail);
                storeProduct.setPrice(-storeProduct.getPrice());
                storeProductService.update(storeProduct,App.Direction.ADD);
            }
        }
    }

    private List<CostOrderDetail> getCostOrderDetails(CostOrder order){
        CostOrderDetail detail = new CostOrderDetail();
        detail.setCostOrderId(order.getId());
        detail.setCustomerId(order.getCustomerId());
        List<CostOrderDetail> costOrderDetails = costOrderDetailMapper.select(detail);
        return costOrderDetails;
    }

    private static StoreProduct getStoreProduct(CostOrderDetail orderDetail){
        StoreProduct storeProduct = new StoreProduct();
        storeProduct.setNumber(0L);
        storeProduct.setCompanyId(orderDetail.getCompanyId());
        storeProduct.setPrice(orderDetail.getPrice());
        storeProduct.setProductId(orderDetail.getProductId());
        storeProduct.setStoreId(orderDetail.getStoreId());
        storeProduct.setUnitId(orderDetail.getUnitId());
        storeProduct.setCustomerId(orderDetail.getCustomerId());
        return storeProduct;
    }

    protected static long getFullTime(String str){
        return DateUtils.parse(str + " 00:00:00").getTime();
    }


}
